package org.vsb.chmireader.utils.tasks;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.dao.DataIntegrityViolationException;
import org.vsb.chmireader.hibernate.dao.SaveChmiElements;
import org.vsb.chmireader.hibernate.entity.ChmiRecord;
import org.vsb.chmireader.hibernate.entity.ChmiRecordKey;
import org.vsb.chmireader.log.LogUtils;

/**
 * Task definition
 * 
 * @author Peta
 * 
 */

@Configurable
public class ReadURLTask implements Runnable {

	static final Logger logger = LogUtils.getLogForMyClass();

	@Autowired
	private SaveChmiElements saveChmiElements;
	
	@Autowired
	private SessionFactory sessionFactory;

	@Resource(name = "configuredTimeout")
	private Integer configuredTimeout;

	@Resource(name = "numerOfAttempts")
	private Integer numerOfAttempts;

	private String url;
	private String nodeName;

	public ReadURLTask(String url, String nodeName) {
		this.url = url;
		this.nodeName = nodeName;
	}

	@Override
	public void run() {
		Date nowDate = new Date();
		if (logger.isDebugEnabled())
			logger.debug(MessageFormat.format(
					"URL = {1}, nodeName={2} at time {3}", url, nodeName,
					nowDate.toString()));
		List<ChmiRecord> chmiRecA = new ArrayList<>();
		ChmiRecord chmiRec = null;
		ChmiRecordKey chmiRecKey = null;
		try {
			Document doc = null;
			for (int u = 0; u < numerOfAttempts; u++) {
				try {
					doc = Jsoup.connect(url).timeout(configuredTimeout).get();
				} catch (SocketTimeoutException ste) {
					if (u >= numerOfAttempts)
						throw new Exception();
				}
			}
			Element table = doc.select("table[class=data_table]").get(1);
			// attribute starts with selector
			Elements tdEtmnts = null;
			String[] separatedBySpace = null;
			for (Element element : table.select("tr[class^=list-row]")) {
				tdEtmnts = element.select("td");

				chmiRecKey = new ChmiRecordKey();
				chmiRecKey.setDateAndTime(tdEtmnts.get(0).text().trim());
				chmiRecKey.setStationName(this.nodeName);

				chmiRec = new ChmiRecord();
				chmiRec.setChmiRecordKey(chmiRecKey);
				separatedBySpace = tdEtmnts.get(0).text().trim().split(" ");
				Calendar cal = Calendar.getInstance();
				cal.set(Calendar.YEAR,
						Integer.parseInt(separatedBySpace[0].split("\\.")[2]));
				cal.set(Calendar.MONTH,
						Integer.parseInt(separatedBySpace[0].split("\\.")[1]) - 1);
				cal.set(Calendar.DAY_OF_MONTH,
						Integer.parseInt(separatedBySpace[0].split("\\.")[0]));
				cal.set(Calendar.HOUR_OF_DAY,
						Integer.parseInt(separatedBySpace[1].split(":")[0]));
				cal.set(Calendar.MINUTE, 0);
				cal.set(Calendar.SECOND, 0);
				cal.set(Calendar.MILLISECOND, 0);
				chmiRec.setStartOfMeasuringPeriod(cal.getTime());
				chmiRec.setSo21h(tdEtmnts.get(0).text());
				chmiRec.setSo224h(tdEtmnts.get(1).text());
				chmiRec.setNo21h(tdEtmnts.get(2).text());
				chmiRec.setCo8h(tdEtmnts.get(3).text());
				chmiRec.setO31h(tdEtmnts.get(4).text());
				chmiRec.setO38h(tdEtmnts.get(5).text());
				chmiRec.setPm101h(tdEtmnts.get(6).text());
				chmiRec.setPm1024h(tdEtmnts.get(7).text());
				chmiRec.setPm251h(tdEtmnts.get(8).text());
				chmiRec.setBzn1h(tdEtmnts.get(9).text());
				if (logger.isDebugEnabled())
					logger.debug(tdEtmnts.text());

				chmiRecA.add(chmiRec);
			}
			saveChmiElements.saveElements(chmiRecA);
		} catch (UnknownHostException uhe) {
			if (logger.isErrorEnabled())
				logger.error("Unknowh host: " + this.url, uhe);
		} catch (SocketTimeoutException ste) {
			if (logger.isErrorEnabled()) {
				logger.error(" Connection failed to given URL: " + this.url
						+ ", application tried to connect " + numerOfAttempts
						+ " times", ste);
			}
		} catch (IOException e) {
			if (logger.isErrorEnabled())
				logger.error("Unknow Exception", e);
		}catch (DataIntegrityViolationException dive) {
			if (logger.isErrorEnabled())
				logger.error("Data integrity Exception", dive);
		} catch (Exception ge) {
			if (logger.isErrorEnabled())
				logger.error("General Exception", ge);
		}finally{
			if (logger.isDebugEnabled())
				logger.debug(sessionFactory.getStatistics().toString());
		}

	}

}
